package com.lsyw.intergrate.controller;

import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONObject;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lsyw.intergrate.common.Result;
import com.lsyw.intergrate.common.StringUtil;
import com.lsyw.intergrate.common.redis.RedisUtil;
import com.lsyw.intergrate.controller.websocket.WebSocketController;
import com.lsyw.intergrate.entity.*;
import com.lsyw.intergrate.entity.common.LoginInfo;
import com.lsyw.intergrate.entity.qo.LoginQo;
import com.lsyw.intergrate.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.*;

import static com.lsyw.intergrate.common.MybatisPlus.ColumnResolver.sysUserCR;
import static com.lsyw.intergrate.common.Result.*;
import static com.lsyw.intergrate.common.StringUtil.checkPwd;
import static com.lsyw.intergrate.common.util.CoordinateTransformUtil.wgs84tobd09;
import static com.lsyw.intergrate.common.util.DateUtil.daysBetween;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author 刘磊
 * @since 2023-04-18
 */
@Api(tags = "公共")
@RestController
@RequestMapping("/index")
public class IndexController {
    @Autowired
    private T0200Service t0200Service;

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private SysUsersRolesService sysUsersRolesService;

    @Autowired
    private UnopDeptService deptService;

    @Autowired
    private SysMenuService sysMenuService;

    @Autowired
    private SysMessageService sysMessageService;
    @Autowired
    private TransportWorkOrderService transportWorkOrderService;

    @Autowired
    private TransportTaskService transportTaskService;

    @Autowired
    private RouteService routeService;

    @Autowired
    private TransportWorkOrderAlarmService transportWorkOrderAlarmService;

    @Autowired
    RedisUtil redisUtil;

    @Value("${yj.ip}")
    private String yjip;
    @Value("${yj.radius}")
    private String radius;
    @Value("${yj.days}")
    private Integer days;

    /**
     * 对接GPS
     */
    @GetMapping("/gps")
    @ApiOperation(value = "对接GPS", notes = "对接GPS", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "jsonStr", value = "对象字符", required = true, paramType = "query", dataType = "String")

    })
    public Result gps(String jsonStr) throws IOException {

        T0200 t0200 = JSON.parseObject(jsonStr, T0200.class);
        t0200.setId(IdUtil.simpleUUID());
        t0200.setDelFlag(0);
        t0200.setGmtCreate(new Date());
        //获取订单id
        LambdaQueryWrapper<TransportWorkOrder> lambda = new QueryWrapper<TransportWorkOrder>().lambda();
        lambda.eq(TransportWorkOrder::getDelFlag, 0);
        lambda.ne(TransportWorkOrder::getStatus, 3);
        // lambda.eq(TransportWorkOrder::getGpsSoilId, t0200.getNo());
        lambda.and(wq -> {
            wq.eq(TransportWorkOrder::getGpsSoilId, t0200.getNo());
            wq.or().eq(TransportWorkOrder::getGpsVehicleId, t0200.getNo());
        });

        TransportWorkOrder transportWorkOrder = new TransportWorkOrder();
        lambda.orderBy(true, true, TransportWorkOrder::getGmtCreate);
        List<TransportWorkOrder> jxzList = this.transportWorkOrderService.list(lambda);
        if (jxzList != null && jxzList.size() > 0) {
            transportWorkOrder = jxzList.get(0);
            t0200.setOrderId(transportWorkOrder.getId());
        }

        double[] doubles = wgs84tobd09(new Double(t0200.getLongitude()), new Double(t0200.getLatitude()));
        t0200.setLongitude(String.valueOf(doubles[0]));
        t0200.setLatitude(String.valueOf(doubles[1]));
        this.t0200Service.save(t0200);
        //放入缓存
        String gps = JSON.toJSONString(t0200);
        redisUtil.set(t0200.getNo() + transportWorkOrder.getId(), gps);


        //监测异常
        String transportTaskId = transportWorkOrder.getTransportTaskId();
        TransportTask task = transportTaskService.getById(transportTaskId);

        Date receiveDate = transportWorkOrder.getReceiveDate();

        if (receiveDate != null && daysBetween(receiveDate, new Date()) >= days) {
            SysMessage sysMessage = new SysMessage();
            sysMessage.setMassifId(task.getMassifId());
            // sysMessage.setGmtCreateUser();
            sysMessage.setGmtCreate(new Date());
            //  sysMessage.setGmtModifiedUser();
            sysMessage.setGmtModified(new Date());
            sysMessage.setDelFlag(0);
            sysMessage.setTransportTaskId(task.getId());
            sysMessage.setStatus(0);
            sysMessage.setName(transportWorkOrder.getName() + "运送的土壤GPS已经超过5天未销毁");
            sysMessage.setRouteId(task.getRouteId());
            sysMessage.setOrderId(transportWorkOrder.getId());
            sysMessageService.save(sysMessage);
            Map<String, Object> map = new HashMap<>();
            map.put("type", 0);
            map.put("message", "有土壤GPS已经超过5天未销毁");
            map.put("order", transportWorkOrder);
            JSONObject object = new JSONObject(map);
            String json = object.toString();
            if (WebSocketController.getOnlineCount() > 0) {
                WebSocketController.sendInfo(json, null);
            }
            transportWorkOrderAlarmService.saveAlarm(t0200.getLatitude() + "," + t0200.getLongitude(), transportWorkOrder, 2, t0200.getNo());
        }

        //监测路线是否偏离
        // HashMap<String, Object> paramMap = new HashMap<>();
        JSONObject paramMap = new JSONObject();
        Route route = routeService.getById(task.getRouteId());
        paramMap.put("line", doRout(route.getRoute()));

        List<Double> now = new ArrayList<>();
        now.add(new Double(t0200.getLongitude()));
        now.add(new Double(t0200.getLatitude()));
        paramMap.put("point", now);
        paramMap.put("radius", radius);
        if (transportWorkOrder.getStatus() != 3) {
            String result = HttpRequest.post(yjip).header("Content-Type", "application/json").body(paramMap.toString()).execute().body();
            if ("False".equals(result)) {
                //发生预警
                transportWorkOrderAlarmService.saveAlarm(t0200.getLatitude() + "," + t0200.getLongitude(), transportWorkOrder, 1, t0200.getNo());
                if (t0200.getNo().equals(transportWorkOrder.getGpsVehicleId())) {
                    Map<String, Object> map = new HashMap<>();
                    map.put("type", 4);
                    map.put("message", "车辆偏离预警GPS");
                    map.put("t0200", t0200);
                    map.put("order", transportWorkOrder);
                    JSONObject object = new JSONObject(map);
                    String json = object.toString();
                    if (WebSocketController.getOnlineCount() > 0) {
                        WebSocketController.sendInfo(json, null);
                    }
                }
                if (t0200.getNo().equals(transportWorkOrder.getGpsSoilId())) {
                    Map<String, Object> map = new HashMap<>();
                    map.put("type", 5);
                    map.put("message", "土壤偏离预警GPS");
                    map.put("t0200", t0200);
                    map.put("order", transportWorkOrder);
                    JSONObject object = new JSONObject(map);
                    String json = object.toString();
                    if (WebSocketController.getOnlineCount() > 0) {
                        WebSocketController.sendInfo(json, null);
                    }
                }
            }

        }
        if (transportWorkOrder.getStatus() == 3) {
            if (t0200.getNo().equals(transportWorkOrder.getGpsVehicleId())) {
                return Result.successResult(null);
            } else {//只推土壤
                Map<String, Object> map = new HashMap<>();
                map.put("type", 2);
                map.put("message", "土壤GPS");
                map.put("t0200", t0200);
                map.put("order", transportWorkOrder);
                JSONObject object = new JSONObject(map);
                String json = object.toString();
                if (WebSocketController.getOnlineCount() > 0) {
                    WebSocketController.sendInfo(json, null);
                }
                return Result.successResult(null);
            }
        }

        //实时推送GPS点位
        if (t0200.getNo().equals(transportWorkOrder.getGpsVehicleId())) {
            Map<String, Object> map = new HashMap<>();
            map.put("type", 1);
            map.put("message", "车辆GPS");
            map.put("t0200", t0200);
            map.put("order", transportWorkOrder);
            JSONObject object = new JSONObject(map);
            String json = object.toString();
            if (WebSocketController.getOnlineCount() > 0) {
                WebSocketController.sendInfo(json, null);
            }
            return Result.successResult(null);
        } else { //只推土壤
            Map<String, Object> map = new HashMap<>();
            map.put("type", 2);
            map.put("message", "土壤GPS");
            map.put("t0200", t0200);
            map.put("order", transportWorkOrder);
            JSONObject object = new JSONObject(map);
            String json = object.toString();
            if (WebSocketController.getOnlineCount() > 0) {
                WebSocketController.sendInfo(json, null);
            }
            return Result.successResult(null);
        }
    }


    /**
     * 登录
     *
     * @return
     */
    @PostMapping("/login")
    @ApiOperation(value = "登录  ", notes = "登录 ", httpMethod = "POST")
    @Transactional
    public Result login(@RequestBody LoginQo loginQo) {
        String name = loginQo.getName();
        String password = loginQo.getPassword();
        //判断是否为空
        if (StringUtil.isEmpty(name) || StringUtil.isEmpty(password)) {
            return errorResult(null, "用户名、密码不能为空");
        }

        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(sysUserCR.columnToString(SysUser::getName), name).eq(sysUserCR.columnToString(SysUser::getIsDelete), 0).eq(sysUserCR.columnToString(SysUser::getStatus), 0);
        List<SysUser> list = this.sysUserService.list(queryWrapper);
        if (CollectionUtils.isEmpty(list)) {
            return errorResult(null, "暂无此用户或已被禁用，请先联系管理员。");
        }
        SysUser user = new SysUser();
        for (SysUser sysUser : list) {
            String salt = sysUser.getSalt();
            String md5 = SecureUtil.md5(password + salt);
            if (sysUser.getPassword().equals(md5)) {
                user = sysUser;
                break;
            }
        }
        String id = user.getId();
        //登录失败
        if (StringUtil.isEmpty(id)) {
            return errorResult(null, "用户名或密码错误。");
        }
        StpUtil.login(id, "PC");
        //获取token
        SaTokenInfo tokenInfo = StpUtil.getTokenInfo();

        if (true) {
            user.setDept(deptService.getById(user.getDeptId()));
            return successResult(new LoginInfo(user, tokenInfo));
        } else {
            return errorResult(null);
        }
    }

    /**
     * 修改密码
     */
    @GetMapping("/update/password")
    @ApiOperation(value = "重置密码", notes = "重置密码", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "password", value = "新密码", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "userId", value = "userId", required = true, paramType = "query", dataType = "String"),
    })
    public Result updatePassword(String userId, String password) {
        boolean b = checkPwd(password);
        if (!b) {
            return new Result(SUCCESS, "密码不符合规范", "密码不符合规范");
        }
        SysUser sysUser = this.sysUserService.getById(userId);

        String salt = IdUtil.simpleUUID();
        sysUser.setSalt(salt);
        sysUser.setStatus(0);
        sysUser.setCreatedTime(new Date());
        sysUser.setPassword(SecureUtil.md5(password + salt));
        System.out.println(sysUser.getPassword());
        this.sysUserService.updateById(sysUser);
        return Result.successResult(null);
    }


    /**
     * 获取用户权限点
     */
    @GetMapping("/get/menu")
    @ApiOperation(value = "获取用户权限点", notes = "获取用户权限点", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户id", required = true, paramType = "query", dataType = "String")
    })
    public Result getMenu(String userId) {
        List<SysMenu> sysMenuLis = new ArrayList<>();
        LambdaQueryWrapper<SysUsersRoles> lambda = new QueryWrapper<SysUsersRoles>().lambda();
        lambda.eq(SysUsersRoles::getDelFlag, 0);
        lambda.eq(SysUsersRoles::getUserId, userId);
        List<SysUsersRoles> list = this.sysUsersRolesService.list(lambda);
        for (SysUsersRoles sysUsersRoles : list) {
            sysMenuLis = this.sysMenuService.getMenuList(sysUsersRoles.getRoleId());
        }
        return Result.successResult(sysMenuLis);
    }

    public static List<Double> doRout(String rout) {
        //  String rout="[[120.235533,31.55406],[120.23554,31.554019],[120.236141,31.554151],[120.2362,31.553987],[120.236329,31.553708],[120.236447,31.55336],[120.236211,31.553219],[120.235787,31.553136],[120.235315,31.553173],[120.235175,31.553278]]";

        rout = rout.replace("]", "");
        rout = rout.replace("[", "");
        String[] split = rout.split(",");
        List<Double> doubles = new ArrayList<>();
        for (String s : split) {
            Double aDouble = new Double(s);
            doubles.add(aDouble);
        }
        System.out.println(doubles);
        return doubles;
    }
}
